#!/bin/bash

# CU MR BULL API 测试脚本
# 用于验证所有API端点的功能

set -e

# 颜色输出
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color

# 配置
API_BASE_URL="http://localhost:3000"
TEST_EMAIL="test@example.com"
TEST_PASSWORD="Test123456!"
TEST_PHONE="+1234567890"
ADMIN_EMAIL="admin@cumrbull.com"
ADMIN_PASSWORD="Admin123456!"

# 全局变量
USER_TOKEN=""
ADMIN_TOKEN=""
USER_ID=""
TEST_RESULTS=()

# 日志函数
log() {
    echo -e "${BLUE}[$(date '+%H:%M:%S')]${NC} $1"
}

log_success() {
    echo -e "${GREEN}[$(date '+%H:%M:%S')] ✓${NC} $1"
    TEST_RESULTS+=("✓ $1")
}

log_error() {
    echo -e "${RED}[$(date '+%H:%M:%S')] ✗${NC} $1"
    TEST_RESULTS+=("✗ $1")
}

log_warning() {
    echo -e "${YELLOW}[$(date '+%H:%M:%S')] ⚠${NC} $1"
}

# HTTP请求函数
api_request() {
    local method="$1"
    local endpoint="$2"
    local data="$3"
    local token="$4"
    
    local curl_cmd="curl -s -X $method"
    
    if [ -n "$token" ]; then
        curl_cmd="$curl_cmd -H 'Authorization: Bearer $token'"
    fi
    
    curl_cmd="$curl_cmd -H 'Content-Type: application/json'"
    
    if [ -n "$data" ]; then
        curl_cmd="$curl_cmd -d '$data'"
    fi
    
    curl_cmd="$curl_cmd '$API_BASE_URL$endpoint'"
    
    eval $curl_cmd
}

# 检查API响应
check_response() {
    local response="$1"
    local expected_status="$2"
    local test_name="$3"
    
    if echo "$response" | jq -e '.success' >/dev/null 2>&1; then
        local success=$(echo "$response" | jq -r '.success')
        if [ "$success" = "$expected_status" ]; then
            log_success "$test_name"
            return 0
        fi
    fi
    
    log_error "$test_name - Response: $response"
    return 1
}

# 等待API服务启动
wait_for_api() {
    log "Waiting for API server to be ready..."
    
    for i in {1..30}; do
        if curl -f "$API_BASE_URL/health" >/dev/null 2>&1; then
            log_success "API server is ready"
            return 0
        fi
        sleep 2
    done
    
    log_error "API server not ready after 30 attempts"
    exit 1
}

# 测试健康检查
test_health_check() {
    log "Testing health check endpoint..."
    
    local response=$(api_request "GET" "/health")
    
    if echo "$response" | jq -e '.status' >/dev/null 2>&1; then
        local status=$(echo "$response" | jq -r '.status')
        if [ "$status" = "healthy" ]; then
            log_success "Health check endpoint"
        else
            log_error "Health check endpoint - Status: $status"
        fi
    else
        log_error "Health check endpoint - Invalid response: $response"
    fi
}

# 测试API根路径
test_api_root() {
    log "Testing API root endpoint..."
    
    local response=$(api_request "GET" "/api")
    
    if echo "$response" | jq -e '.success' >/dev/null 2>&1; then
        log_success "API root endpoint"
    else
        log_error "API root endpoint - Response: $response"
    fi
}

# 测试用户注册
test_user_registration() {
    log "Testing user registration..."
    
    local data='{
        "email": "'$TEST_EMAIL'",
        "password": "'$TEST_PASSWORD'",
        "phone": "'$TEST_PHONE'",
        "name": "Test User"
    }'
    
    local response=$(api_request "POST" "/api/auth/register" "$data")
    
    if check_response "$response" "true" "User registration"; then
        USER_ID=$(echo "$response" | jq -r '.data.user.id')
    fi
}

# 测试用户登录
test_user_login() {
    log "Testing user login..."
    
    local data='{
        "email": "'$TEST_EMAIL'",
        "password": "'$TEST_PASSWORD'"
    }'
    
    local response=$(api_request "POST" "/api/auth/login" "$data")
    
    if check_response "$response" "true" "User login"; then
        USER_TOKEN=$(echo "$response" | jq -r '.data.token')
    fi
}

# 测试管理员登录
test_admin_login() {
    log "Testing admin login..."
    
    local data='{
        "email": "'$ADMIN_EMAIL'",
        "password": "'$ADMIN_PASSWORD'"
    }'
    
    local response=$(api_request "POST" "/api/auth/login" "$data")
    
    if check_response "$response" "true" "Admin login"; then
        ADMIN_TOKEN=$(echo "$response" | jq -r '.data.token')
    fi
}

# 测试用户信息获取
test_user_profile() {
    log "Testing user profile..."
    
    if [ -z "$USER_TOKEN" ]; then
        log_error "User profile - No user token available"
        return
    fi
    
    local response=$(api_request "GET" "/api/users/profile" "" "$USER_TOKEN")
    check_response "$response" "true" "User profile"
}

# 测试菜单获取
test_menu_categories() {
    log "Testing menu categories..."
    
    local response=$(api_request "GET" "/api/menu/categories")
    check_response "$response" "true" "Menu categories"
}

# 测试菜单项目
test_menu_items() {
    log "Testing menu items..."
    
    local response=$(api_request "GET" "/api/menu/items")
    check_response "$response" "true" "Menu items"
}

# 测试支付方式
test_payment_methods() {
    log "Testing payment methods..."
    
    if [ -z "$USER_TOKEN" ]; then
        log_error "Payment methods - No user token available"
        return
    fi
    
    local response=$(api_request "GET" "/api/payments/methods" "" "$USER_TOKEN")
    check_response "$response" "true" "Payment methods"
}

# 测试订单创建
test_order_creation() {
    log "Testing order creation..."
    
    if [ -z "$USER_TOKEN" ]; then
        log_error "Order creation - No user token available"
        return
    fi
    
    local data='{
        "items": [
            {
                "menu_item_id": 1,
                "quantity": 2,
                "customizations": ["Extra spicy"]
            }
        ],
        "delivery_address": "123 Test Street, Test City",
        "delivery_time": "ASAP",
        "notes": "Test order"
    }'
    
    local response=$(api_request "POST" "/api/orders" "$data" "$USER_TOKEN")
    check_response "$response" "true" "Order creation"
}

# 测试优惠券获取
test_coupons() {
    log "Testing available coupons..."
    
    if [ -z "$USER_TOKEN" ]; then
        log_error "Coupons - No user token available"
        return
    fi
    
    local response=$(api_request "GET" "/api/coupons/available" "" "$USER_TOKEN")
    check_response "$response" "true" "Available coupons"
}

# 测试管理员仪表板
test_admin_dashboard() {
    log "Testing admin dashboard..."
    
    if [ -z "$ADMIN_TOKEN" ]; then
        log_error "Admin dashboard - No admin token available"
        return
    fi
    
    local response=$(api_request "GET" "/api/admin/dashboard/stats" "" "$ADMIN_TOKEN")
    check_response "$response" "true" "Admin dashboard"
}

# 测试管理员用户管理
test_admin_users() {
    log "Testing admin user management..."
    
    if [ -z "$ADMIN_TOKEN" ]; then
        log_error "Admin users - No admin token available"
        return
    fi
    
    local response=$(api_request "GET" "/api/admin/users" "" "$ADMIN_TOKEN")
    check_response "$response" "true" "Admin user management"
}

# 测试错误处理
test_error_handling() {
    log "Testing error handling..."
    
    # 测试无效端点
    local response=$(api_request "GET" "/api/invalid-endpoint")
    if echo "$response" | jq -e '.success' >/dev/null 2>&1; then
        local success=$(echo "$response" | jq -r '.success')
        if [ "$success" = "false" ]; then
            log_success "Error handling - Invalid endpoint"
        else
            log_error "Error handling - Invalid endpoint should return success: false"
        fi
    else
        log_success "Error handling - Invalid endpoint (404 response)"
    fi
    
    # 测试无效认证
    local response=$(api_request "GET" "/api/users/profile" "" "invalid-token")
    if echo "$response" | jq -e '.success' >/dev/null 2>&1; then
        local success=$(echo "$response" | jq -r '.success')
        if [ "$success" = "false" ]; then
            log_success "Error handling - Invalid token"
        else
            log_error "Error handling - Invalid token should return success: false"
        fi
    else
        log_success "Error handling - Invalid token (401 response)"
    fi
}

# 性能测试
test_performance() {
    log "Testing API performance..."
    
    local start_time=$(date +%s%N)
    local response=$(api_request "GET" "/health")
    local end_time=$(date +%s%N)
    
    local duration=$(( (end_time - start_time) / 1000000 )) # Convert to milliseconds
    
    if [ $duration -lt 1000 ]; then
        log_success "Performance test - Health check: ${duration}ms"
    else
        log_warning "Performance test - Health check slow: ${duration}ms"
    fi
}

# 清理测试数据
cleanup_test_data() {
    log "Cleaning up test data..."
    
    if [ -n "$USER_ID" ] && [ -n "$ADMIN_TOKEN" ]; then
        local response=$(api_request "DELETE" "/api/admin/users/$USER_ID" "" "$ADMIN_TOKEN")
        if echo "$response" | jq -e '.success' >/dev/null 2>&1; then
            log_success "Test user cleanup"
        else
            log_warning "Test user cleanup failed - may need manual cleanup"
        fi
    fi
}

# 显示测试结果
show_test_results() {
    echo
    echo "=== Test Results ==="
    
    local passed=0
    local failed=0
    
    for result in "${TEST_RESULTS[@]}"; do
        echo "$result"
        if [[ $result == ✓* ]]; then
            ((passed++))
        else
            ((failed++))
        fi
    done
    
    echo
    echo "Total: $((passed + failed)) tests"
    echo -e "${GREEN}Passed: $passed${NC}"
    echo -e "${RED}Failed: $failed${NC}"
    
    if [ $failed -eq 0 ]; then
        echo -e "${GREEN}All tests passed! 🎉${NC}"
        return 0
    else
        echo -e "${RED}Some tests failed! ❌${NC}"
        return 1
    fi
}

# 主函数
main() {
    echo "=== CU MR BULL API Test Suite ==="
    echo "Testing API at: $API_BASE_URL"
    echo
    
    wait_for_api
    
    # 基础测试
    test_health_check
    test_api_root
    
    # 认证测试
    test_user_registration
    test_user_login
    test_admin_login
    
    # 功能测试
    test_user_profile
    test_menu_categories
    test_menu_items
    test_payment_methods
    test_order_creation
    test_coupons
    
    # 管理员测试
    test_admin_dashboard
    test_admin_users
    
    # 错误处理测试
    test_error_handling
    
    # 性能测试
    test_performance
    
    # 清理
    cleanup_test_data
    
    # 显示结果
    show_test_results
}

# 处理命令行参数
while [[ $# -gt 0 ]]; do
    case $1 in
        --url)
            API_BASE_URL="$2"
            shift 2
            ;;
        --help)
            echo "Usage: $0 [options]"
            echo "Options:"
            echo "  --url URL    API base URL (default: http://localhost:3000)"
            echo "  --help       Show this help message"
            exit 0
            ;;
        *)
            echo "Unknown option: $1"
            exit 1
            ;;
    esac
done

# 检查依赖
command -v curl >/dev/null 2>&1 || { echo "curl is required but not installed."; exit 1; }
command -v jq >/dev/null 2>&1 || { echo "jq is required but not installed."; exit 1; }

# 执行测试
if [ "${BASH_SOURCE[0]}" = "${0}" ]; then
    main "$@"
fi